#include <iostream>
#include <queue>
#include <thread>
#include <atomic>
#include <chrono>

#define N 10

typedef struct msg_node_s
{
    struct msg_node_s *next;
    int value;
} msg_node_t;

class A {
private:
    std::thread thrd_;
    std::atomic<bool> shutdown_;
    msg_node_t* volatile front_;
    msg_node_t* volatile near_;

private:
    void consume() {
        std::cout << "[ worker ] " << " waiting..." << std::endl;

        for (;;)
        {
            if (front_ == near_)
            {
                if (shutdown_)
                    break;

                std::this_thread::sleep_for(std::chrono::microseconds(10000));
            }
            else
            {
                msg_node_t *p = front_;
                std::cout << "[ worker ] get msg: " << p->value << std::endl;

                front_ = p->next;
                delete p;
            }
        }

        std::cout << "[ worker ] exited." << std::endl;
    }

public:
    A(): shutdown_(false) {
        front_ = near_ = new msg_node_t;
        front_->next = NULL;
    }

    ~A() {
        shutdown_ = true;
        thrd_.join();

        while (front_)
        {
            near_ = front_->next;
            delete front_;
            front_ = near_;
        }

        std::cout << "[ A.~A ] finished." << std::endl;
    }

    void Add(int msg)
    {
        msg_node_t *p = new msg_node_t;
        p->next = NULL;

        near_->next = p;
        near_->value = msg;

        near_ = p;
    }

    void Start() {
        thrd_ = std::thread(&A::consume, this);
    }
};


int main()
{
    A *a = new A;
    a->Start();

    for (int i = 0; i < N; ++i)
    {
        a->Add(i);
        std::this_thread::sleep_for(std::chrono::microseconds(100000));
    }

    delete a;

    return 0;
}
